<template>
  <div class="stat-card">
    <div class="stat-card__icon" :style="{ background: iconBg }">
      <ElIcon :size="32" :color="iconColor">
        <component :is="icon" />
      </ElIcon>
    </div>
    
    <div class="stat-card__content">
      <div class="stat-card__value">
        <span v-if="prefix" class="prefix">{{ prefix }}</span>
        <span class="number">{{ animatedValue }}</span>
        <span v-if="suffix" class="suffix">{{ suffix }}</span>
      </div>
      <div class="stat-card__label">{{ label }}</div>
    </div>
    
    <div v-if="trend" class="stat-card__trend" :class="trendClass">
      <ElIcon>
        <component :is="trendIcon" />
      </ElIcon>
      <span>{{ trend }}</span>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { ArrowUp, ArrowDown, Minus } from '@element-plus/icons-vue'

const props = defineProps({
  // 图标组件
  icon: {
    type: [String, Object],
    required: true
  },
  // 图标颜色
  iconColor: {
    type: String,
    default: '#ffffff'
  },
  // 图标背景色
  iconBg: {
    type: String,
    default: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'
  },
  // 数值
  value: {
    type: [Number, String],
    required: true
  },
  // 前缀
  prefix: {
    type: String,
    default: ''
  },
  // 后缀
  suffix: {
    type: String,
    default: ''
  },
  // 标签
  label: {
    type: String,
    required: true
  },
  // 趋势（如：+12%、-5%）
  trend: {
    type: String,
    default: ''
  },
  // 是否启用数字动画
  animated: {
    type: Boolean,
    default: true
  },
  // 动画持续时间（毫秒）
  duration: {
    type: Number,
    default: 1000
  }
})

const animatedValue = ref(0)

// 趋势图标
const trendIcon = computed(() => {
  if (!props.trend) return Minus
  const firstChar = props.trend.charAt(0)
  if (firstChar === '+') return ArrowUp
  if (firstChar === '-') return ArrowDown
  return Minus
})

// 趋势样式类
const trendClass = computed(() => {
  if (!props.trend) return ''
  const firstChar = props.trend.charAt(0)
  if (firstChar === '+') return 'trend-up'
  if (firstChar === '-') return 'trend-down'
  return 'trend-neutral'
})

// 数字动画
const animateValue = (start, end, duration) => {
  if (!props.animated) {
    animatedValue.value = end
    return
  }
  
  const startTime = Date.now()
  const range = end - start
  
  const updateValue = () => {
    const now = Date.now()
    const elapsed = now - startTime
    const progress = Math.min(elapsed / duration, 1)
    
    // 使用缓动函数
    const easeOutQuad = progress * (2 - progress)
    animatedValue.value = Math.floor(start + range * easeOutQuad)
    
    if (progress < 1) {
      requestAnimationFrame(updateValue)
    } else {
      animatedValue.value = end
    }
  }
  
  requestAnimationFrame(updateValue)
}

// 监听 value 变化
watch(() => props.value, (newVal) => {
  const numValue = typeof newVal === 'number' ? newVal : parseInt(newVal) || 0
  animateValue(animatedValue.value, numValue, props.duration)
}, { immediate: true })

onMounted(() => {
  const numValue = typeof props.value === 'number' ? props.value : parseInt(props.value) || 0
  animateValue(0, numValue, props.duration)
})
</script>

<style lang="scss" scoped>
.stat-card {
  display: flex;
  align-items: center;
  gap: $spacing-lg;
  padding: $spacing-xl;
  background: var(--bg-primary);
  border-radius: $radius-lg;
  box-shadow: var(--shadow-md);
  @include transition(all);
  
  &:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-xl);
  }
  
  &__icon {
    @include flex-center;
    width: 64px;
    height: 64px;
    border-radius: $radius-md;
    flex-shrink: 0;
  }
  
  &__content {
    flex: 1;
    min-width: 0;
  }
  
  &__value {
    font-size: $font-size-3xl;
    font-weight: $font-weight-bold;
    color: var(--text-primary);
    line-height: 1.2;
    margin-bottom: $spacing-xs;
    
    .prefix,
    .suffix {
      font-size: $font-size-lg;
      font-weight: $font-weight-medium;
      color: var(--text-secondary);
    }
    
    .number {
      font-variant-numeric: tabular-nums;
    }
  }
  
  &__label {
    font-size: $font-size-sm;
    color: var(--text-secondary);
    font-weight: $font-weight-medium;
  }
  
  &__trend {
    display: flex;
    align-items: center;
    gap: $spacing-xs;
    padding: $spacing-xs $spacing-sm;
    border-radius: $radius-sm;
    font-size: $font-size-sm;
    font-weight: $font-weight-medium;
    
    &.trend-up {
      color: #67c23a;
      background: rgba(103, 194, 58, 0.1);
    }
    
    &.trend-down {
      color: #f56c6c;
      background: rgba(245, 108, 108, 0.1);
    }
    
    &.trend-neutral {
      color: var(--text-secondary);
      background: var(--bg-secondary);
    }
  }
}

// 响应式
@include respond-to('sm') {
  .stat-card {
    &__icon {
      width: 56px;
      height: 56px;
      
      .el-icon {
        font-size: 28px !important;
      }
    }
    
    &__value {
      font-size: $font-size-2xl;
    }
  }
}
</style>

